package util;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

public class CollectionUtils {
    /**
     * Groups elements by non unique key, evaluated by predicate.
     * 
     * @param from
     * @param groupByPredicate
     * @return map of values grouped by specified key.
     * @author Mykhaylo Adamovych
     */
    public static final <K, V> Map<K, List<V>> groupBy(Collection<V> from, Predicate<V, K> groupByPredicate) {
        if (from == null || groupByPredicate == null)
            return null;
        final Map<K, List<V>> result = new TreeMap<K, List<V>>();
        for (final V value : from) {
            final K groupByElement = groupByPredicate.evaluate(value);
            if (groupByElement == null)
                continue;
            List<V> values = result.get(groupByElement);
            if (values == null) {
                values = new LinkedList<V>();
                result.put(groupByElement, values);
            }
            values.add(value);
        }
        return result;
    }
    
    /**
     * Check if each item in the collection is instance of some class. NULLs are not taken into consideration.
     * 
     * @param clazz
     * @param collection
     * @return
     * @author Mykhaylo Adamovych
     */
    public static boolean instanceOf(Class<?> clazz, Object collection) {
        if (!(collection instanceof Collection<?>))
            return false;
        for (Object item : (Collection<?>) collection)
            if (item != null && !clazz.isAssignableFrom(item.getClass()))
                return false;
        return true;
    }
}
